package com.prodog.gamemodule.fight.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.prodog.command.annonations.Service;
import com.prodog.command.entity.CommandResult;
import com.prodog.command.entity.RoleGameCommand;
import com.prodog.gamemodule.fight.action.entity.FightActionSetRes;
import com.prodog.gamemodule.fight.action.util.ActionUtil;
import com.prodog.gamemodule.fight.fightobj.builder.FightObjBuilder;
import com.prodog.gamemodule.fight.fightobj.entity.FightObj;
import com.prodog.gamemodule.fight.fightobj.factory.FightObjBuilderFactory;
import com.prodog.gamemodule.fight.service.FightService;
import com.prodog.gamemodule.fight.session.FightSession;
import com.prodog.gamemodule.fight.session.FightSessionManager;
import com.prodog.gamemodule.fight.util.FightUtil;
import com.prodog.gamemodule.fight.wrapper.FightSessionWrapper;
import com.prodog.gamemodule.gameworld.map.wrapper.GameMapWrapper;
import com.prodog.gamemodule.gameworld.monster.entity.Monster;
import com.prodog.gamemodule.gameworld.monster.wrapper.MonsterWrapper;
import com.prodog.usermodule.role.entity.RoleInfo;
import com.prodog.usermodule.role.wrapper.RoleInfoWrapper;
import lombok.RequiredArgsConstructor;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

@Service
@RequiredArgsConstructor
public class FightServiceImpl implements FightService {
    private final RoleInfoWrapper roleInfoWrapper;
    private final GameMapWrapper gameMapWrapper;
    private final MonsterWrapper monsterWrapper;
    private final FightSessionWrapper fightSessionWrapper;

    @Override
    public CommandResult fight(RoleGameCommand command) {
        //获取队伍中的人和地图遇到的怪物(数量为(队伍人数-1)*2 ~ 队伍人数*2 最少1个)
        List<RoleInfo> roleInfos = Arrays.asList(roleInfoWrapper.getById(command.getRoleId()));
        Integer monsterNum = RandomUtil.randomInt((roleInfos.size() - 1) * 2, roleInfos.size() * 2 + 1);
        monsterNum = monsterNum == 0 ? 1 : monsterNum;
        List<Monster> monsters = monsterWrapper.getByIds(gameMapWrapper.getById(command.getRoleInfo().getMapId()).getMonsters());
        List<Monster> fightMonsters = new ArrayList<>();
        for (Integer i = 0; i < monsterNum; i++) {
            Collections.shuffle(monsters);
            fightMonsters.add(monsters.get(0));
        }

        FightObjBuilderFactory factory = new FightObjBuilderFactory();
        //封装为战斗对象 存入战斗session
        FightObjBuilder roleInfoBuilder = factory.getBuilder(RoleInfo.class);
        List<FightObj> fightObjs = new ArrayList<>();
        roleInfos.forEach(roleInfo -> {
            FightObj fightObj = roleInfoBuilder.build(roleInfo);
            roleInfo.setFightUuid(fightObj.getUuid());
            fightObjs.add(fightObj);
        });

        FightObjBuilder monsterBuilder = factory.getBuilder(Monster.class);
        fightMonsters.forEach(monster -> fightObjs.add(monsterBuilder.build(monster)));

        //战斗session存入战斗会话管理器
        FightSession session = new FightSession(fightObjs);
        session.setId(IdUtil.simpleUUID());
        fightObjs.forEach(obj -> obj.setSessionId(session.getId()));
        fightSessionWrapper.save(session);
        FightSessionManager.put(session.getId(), session);

        //修改玩家状态和战斗会话Id 保存
        roleInfos.forEach(roleInfo -> {
            roleInfo.setFightSessionId(session.getId());
            roleInfo.setState(2);
            roleInfoWrapper.save(roleInfo);
        });
        //返回战斗进入成功
        return CommandResult.success("成功进入战斗！战斗信息如下：\n" + FightUtil.fightInfo(session, roleInfos.get(0).getFightUuid()));
    }

    @Override
    public CommandResult attack(RoleGameCommand command, Integer index) {
        if (command.getRoleInfo().getState() != 2) {
            CommandResult res = fight(command);
            if (res.getCode() != 200) {
                return res;
            }
        }
        command.setRoleInfo(roleInfoWrapper.getById(command.getRoleId()));
        //获取session
        FightSession session = fightSessionWrapper.getById(command.getRoleInfo().getFightSessionId());
        FightObj obj = session.getObjsByUuid().get(command.getRoleInfo().getFightUuid());
        List<FightObj> enemys = FightUtil.getEnemys(session, obj);
        List<FightObj> aliveEnemys = FightUtil.getAliveEnemys(session, obj);
        if (index == null) {
            index = aliveEnemys.size() > 0 ? enemys.indexOf(aliveEnemys.get(0)) + 1 : 1;
        }
        FightActionSetRes fightActionSetRes = ActionUtil.setAttackAction(session, obj.getUuid(), index - 1);
        if (!fightActionSetRes.isSuccess()) {
            return CommandResult.failure(command.getRoleInfo().getPrefix() + fightActionSetRes.getMsg());
        }
        return CommandResult.success(session.run(obj.getUuid()));
    }
}
